/**
 * axios全局配置
 * TODO: 拦截器全局配置，根据实际情况修改
 */
import axios from 'axios'
import router from '../router'
import { Message } from 'element-ui'
import Cookies from 'js-cookie'
import Auth from '@/util/auth'

var CancelToken = axios.CancelToken;
// var source = CancelToken.source();
// var requestList = []

/**
 * Token校验
 * @param {function} cancel - 中断函数
 * @param {function} callback -  回调
 * @description 校验Token是否过期，如果Token过期则跳转到登陆页
 */
function checkToken(cancel, callback){
    if(Auth.hasToken()){
        callback()

    } else {
        console.log(`Token 不存在，请求路径: ${router.currentRoute.path} `);
        if(router.currentRoute.path != '/login'){
            // BUG: 无法保证一定会中断所有请求
            cancel();
            router.push('/login')
        }
    }
}

/**
 * 阻止短时间内的重复请求
 * @param {string} url - 当前请求地址
 * @param {function} c - 中断请求函数
 * @description 每个请求发起前先判断当前请求是否存在于RequestList中，
 *              如果存在则取消该次请求，如果不存在则加入RequestList中，
 *              当请求完成后500ms时，清除RequestList中对应的该请求。
 */
/*function stopRepeatRequest(url, c){
    for( let i = 0; i < requestList.length; i++){
        if(requestList[i] === url){
            c();
            return
        }
    }
    requestList.push(url)
}*/


// 超时设置
const Axios = axios.create({
    baseURL: '/api',
    responseType: 'json',
    // 请求超时时间
    timeout: 5000
});


// http request 拦截器
// 每次请求都为http头增加Authorization字段，其内容为token
Axios.interceptors.request.use(
    config => {
        let cancel;
        config.cancelToken = new CancelToken(function executor(c) {
            cancel = c;
        });

        if(config.url !== 'ajaxLogin'){
            checkToken(cancel, function(){
                Auth.setLoginStatus()
                config.headers.Authorization = Cookies.get('token');
            });
        }

        //stopRepeatRequest(config.url, cancel);
        return config;
    },
    err => {
        return Promise.reject(err);
    }
);

/*function removeUrlFromList(url){
    for( let i = 0; i < requestList.length; i++){
        if(requestList[i] === url){
            // 注意，不能保证500ms必定执行，详情请了解JS的异步机制
            //setTimeout(function(){
            requestList.splice(i,1);
            //}, 500)
            break
        }
    }
}*/

// http response 拦截器
// 针对响应代码确认跳转到对应页面
Axios.interceptors.response.use(
    response => {
        console.log("response in ajax.js", response);
        //removeUrlFromList(response.config.url);
        if(response.data.status === 500){
            Message({
                message: `${response.data.msg}`,
                type: 'error',
                duration: 5000
            });
            return Promise.reject(`${response.data.msg}`)
        }else {
            if(response.data.msg){
                Message({
                    message: `${response.data.msg}`,
                    type: 'success',
                    duration: 5000
                });
            }
            return Promise.resolve(response.data)
        }
    },
    err => {
        console.log("error: ", err);
        if (err && err.response) {
            switch (err.response.status) {
                case 400:
                    err.message = '错误请求'
                    break;
                case 401:
                    err.message = '未授权，请重新登录'
                    router.push('error/401');
                    break;
                case 403:
                    err.message = '拒绝访问'
                    router.push('error/403');
                    break;
                case 404:
                    err.message = '请求错误,未找到该资源'
                    router.push('error/404');
                    break;
                case 405:
                    err.message = '请求方法未允许'
                    break;
                case 408:
                    err.message = '请求超时'
                    break;
                case 500:
                    err.message = '服务器端出错'
                    router.push('error/500');
                    break;
                case 501:
                    err.message = '网络未实现'
                    break;
                case 502:
                    err.message = '网络错误'
                    break;
                case 503:
                    err.message = '服务不可用'
                    break;
                case 504:
                    err.message = '网络超时'
                    break;
                case 505:
                    err.message = 'http版本不支持该请求'
                    break;
                default:
                    err.message = `连接错误${err.response.status}`

            }

            Message({
                message: `服务器错误！错误消息：${err.message}`,
                type: 'error',
                duration: 5000
            });
        } else {
            err.message = "超时或 session 过期"
        }

        return Promise.reject(err.response)

    }
);

export default {
    //get请求
    get (url, param) {
        return new Promise(resolve => {
            Axios({
                method: 'get',
                url,
                params: param
            }).then(res => {
                resolve(res)
            })
        })
    },
    //post请求
    post (url, param) {
        return new Promise(resolve => {
            Axios({
                method: 'post',
                url,
                data: param
            }).then(res => {
                resolve(res)
            })
        })
    },
    put (url, param) {
        return new Promise(resolve => {
            Axios({
                method: 'put',
                url,
                data: param
            }).then(res => {
                resolve(res)
            })
        })
    },
    delete (url, param) {
        return new Promise(resolve => {
            Axios({
                method: 'delete',
                url,
                data: param
            }).then(res => {
                resolve(res)
            })
        })
    }
}
